#include "store_app.h"

// 系统数据读取与保存函数
static bool(*SysParamReadFunction)(uint8_t reg, uint8_t* data, uint32_t len);
static bool(*SysParamWriteFunction)(uint8_t reg, uint8_t* data, uint32_t len);

// 系统默认的参数值
static const SysParam_t g_sysParamDefault =
{
    .magicCode = MAGIC_CODE,
    .modbusAddr = 0x01,
    .pwmDuty = 20,
    .crcVal = 0xef,// 默认CRC为0，首次写入时会计算正确值
};

// 保持系统当前的参数值
static SysParam_t sysParamCurrent;

/**
 * @desc  : 读写函数注册
 * @date  : 2025-04-21
 * @author: AnRui
 * @note  : 根据储存方式的不同 注册对应的函数
 */
void SysParamFunctionReg(bool(*readFunc)(uint8_t reg, uint8_t* data, uint32_t len), bool(*writeFunc)(uint8_t reg, uint8_t* data, uint32_t len)) {
    SysParamReadFunction = readFunc;
    SysParamWriteFunction = writeFunc;
}


/**
 * @desc  : 从储存区域读取系统参数并校验
 * @date  : 2025-04-21
 * @author: AnRui
 * @param : reg - {参数说明}:
 * @param : sysParam - {参数说明}:
 * @param : len - {参数说明}:
 * @return: true
 * @return: false
 * @note  :
 */
SysParamStatusCode_e ReadSysDataAndCheck(uint8_t reg, SysParam_t* sysParam, uint32_t len) {

    uint8_t* sysParam_uint8 = (uint8_t*)sysParam;
    // 从储存区域读取数据
    if (!SysParamReadFunction(reg, sysParam_uint8, len)) { return SPS_READ_STORE_FAIL; }
    // 魔数值校验
    if (sysParam->magicCode != MAGIC_CODE) {
        return SPS_READ_MAGIC_MISMATCH;
    }
    // CRC校验
    if (sysParam_uint8[len - 1] != MathCalcCrc8(sysParam_uint8, len - 1)) {
        // printf("crcVal:%x\n,math:%x\n", sysParam->crcVal, MathCalcCrc8((uint8_t*)sysParam, len - 1));
        return SPS_READ_CRC_MISMATCH;
    }
    return SPS_OK;
}




/**
 * @desc  : 从储存区域中读取系统参数
 * @date  : 2025-04-21
 * @author: AnRui
 * @param : sysParam - {参数说明}:
 * @return: true
 * @return: false
 * @note  :
 */
SysParamStatusCode_e ReadSysParam(SysParam_t* sysParam) {
    uint16_t sysParamLen = sizeof(SysParam_t);
    SysParamStatusCode_e res = SPS_OK;
    // 读取主数据区域
    res = ReadSysDataAndCheck(SYSPARAM_START_ADDR, sysParam, sysParamLen);
    if (res == SPS_OK) {
        return SPS_OK;
    }
    // 读取后备区域
    res = ReadSysDataAndCheck(BACKUP_START_ADDR, sysParam, sysParamLen);
    if (res == SPS_OK) {
        return SPS_OK;
    }
    return res;
}

SysParamStatusCode_e WriteSysDataAndAddCheck(uint8_t reg, SysParam_t* sysParam, uint32_t len) {
    // 数据长度校验
    if (len > SYSPARAM_MAX_SIZE) { return SPS_DATA_LEN_OVERFLOW; }
    // 添加crc
    uint8_t* sysParam_uint8 = (uint8_t*)sysParam;
    sysParam_uint8[len - 1] = MathCalcCrc8(sysParam_uint8, len - 1);
    if (!SysParamWriteFunction(reg, sysParam_uint8, len)) {
        return SPS_WRITE_STORE_FAIL;
    }
    return SPS_OK;
}


/**
 * @desc  : 向储存区域写入系统参数
 * @date  : 2025-04-21
 * @author: AnRui
 * @param : sysParam - {参数说明}:
 * @return: true
 * @return: false
 * @note  :
 */
SysParamStatusCode_e WriteSysParam(SysParam_t* sysParam) {
    uint16_t sysParamLen = sizeof(SysParam_t);
    // 写入到主数据区域
    if (WriteSysDataAndAddCheck(SYSPARAM_START_ADDR, sysParam, sysParamLen) != SPS_OK) {
        return SPS_WRITE_PRIMARY_FAIL;
    }
    // 写入到备份数据区域
    if (WriteSysDataAndAddCheck(BACKUP_START_ADDR, sysParam, sysParamLen) != SPS_OK) {
        return SPS_WRITE_BACKUP_FAIL;
    }
    return SPS_OK;
}

/**
 * @desc  : 修改系统参数之modbusAddr
 * @date  : 2025-04-22
 * @author: AnRui
 * @param : addr - {参数说明}:
 * @return: true
 * @return: false
 * @note  :
 */
bool UpdateSysParamModbusAddr(uint8_t addr) {
    if (sysParamCurrent.modbusAddr == addr) {
        return true;
    }
    SysParam_t tmp = sysParamCurrent;
    tmp.modbusAddr = addr;
    SysParamStatusCode_e res = SPS_OK;
    res = WriteSysParam(&tmp);
    if (res != SPS_OK) {
        return false;
    }
    sysParamCurrent.modbusAddr = addr;
    return true;
}




/**
 * @desc  : 系统参数初始化
 * @date  : 2025-04-21
 * @author: AnRui
 * @return: SysParam_t
 * @note  : 如果
 */
void InitSysParam(void) {
    // 注册系统参数读取保存函数
    SysParamFunctionReg(ReadEepromData, WriteEepromData);
    SysParam_t sysParam;
    SysParamStatusCode_e res = ReadSysParam(&sysParam);
    if (res == SPS_OK) {
        sysParamCurrent = sysParam;
    } else {
        sysParamCurrent = g_sysParamDefault;
        (void)WriteSysParam(&sysParamCurrent);
    }
}



/**
 * @desc  : 获取系统当前参数
 * @date  : 2025-04-22
 * @author: AnRui
 * @return: SysParam_t
 * @note  :
 */
SysParam_t GetSysParam() {
    return sysParamCurrent;
}
